home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / gnuish / mkinf10 / pc_term.c < prev    next >
C/C++ Source or Header  |  1990-11-01  |  11KB  |  476 lines

  1. /* pc_term.c - BIOS video calls for GNU info
  2.    Copyright (C) 1990 Free Software Foundation, Inc.
  3.    Thorsten Ohl <td12@ddagsi3.bitnet>, 1990
  4.  
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 1, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.    $Header: e:/gnu/info/RCS/pc_term.c 0.6 90/10/26 20:26:20 tho Exp $
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <malloc.h>
  25. #include <conio.h>
  26. #include <dos.h>
  27.  
  28. #include "pc_term.h"
  29.  
  30. unsigned char term_normal_attrib = NORMAL_ATTRIB;
  31. unsigned char term_inverse_attrib = INVERSE_ATTRIB;
  32.  
  33. /* Higher level functions.  */
  34. void clrscr (void);
  35. void clreop (void);
  36. void clreol (void);
  37. void write_char (int c);
  38. void textattr (unsigned char attrib);
  39.  
  40. /* Lowest level BIOS calls.  */
  41. void set_cursor_position (unsigned char row, unsigned char col);
  42. void scroll_up_active_page (unsigned char lines, unsigned char attrib,
  43.                 unsigned char top_row, unsigned char left_col,
  44.                 unsigned char bot_row, unsigned char right_col);
  45.  
  46.  
  47. /* supplied by info.c */
  48. extern void clear_eop_slowly (void);
  49.  
  50. /* Main switch  */
  51.  
  52. void
  53. do_term (int command)
  54. {
  55.   if (command < 0400)
  56.     /* A character.  */
  57.     write_char (command);
  58.   else
  59.     /* Something less trivial.  */
  60.     switch (command)
  61.       {
  62.       case terminal_ear_bell:
  63.     putchar ('\a');
  64.     break;
  65.  
  66.       case terminal_clearEOP:
  67.     clreop ();
  68.     break;
  69.  
  70.       case terminal_clearEOL:
  71.     clreol ();
  72.     break;
  73.  
  74.       case terminal_use_begin:
  75.     case terminal_use_end:
  76.     /* NOP */
  77.     break;
  78.  
  79.       case terminal_inverse_begin:
  80.     textattr (term_inverse_attrib);
  81.     break;
  82.  
  83.       case terminal_end_attributes:
  84.     textattr (term_normal_attrib);
  85.     break;
  86.  
  87.       default:
  88.     clrscr ();
  89.     fprintf (stderr, "Internal error: Unknown terminal command.\n");
  90.     exit (0);
  91.     break;
  92.     }
  93. }
  94.  
  95. #ifdef USE_ASSEMBLER
  96.  
  97. #define _ax    ax
  98. #define _bx    bx
  99. #define _cx    cx
  100. #define _dx    dx
  101. #define _si    si
  102. #define _di    di
  103.  
  104. #define _cy
  105.  
  106. #define _ah    ah
  107. #define _al    al
  108. #define _bh    bh
  109. #define _bl    bl
  110. #define _ch    ch
  111. #define _cl    cl
  112. #define _dh    dh
  113. #define _dl    dl
  114.  
  115. #define _es    es
  116. #define _cs    cs
  117. #define _ss    ss
  118. #define _ds    ds
  119.  
  120.  
  121. /* Careful with semicolons here! */
  122.  
  123. #define    _byte            byte ptr
  124. #define _alloc_regs
  125. #define _alloc_regs_x
  126. #define _push(reg)        _asm push reg
  127. #define _pop(reg)        _asm pop reg
  128. #define _mov(dest,source)    _asm mov dest, source
  129. #define _mov_ax(dest,source)    _asm mov ax, source _asm mov dest, ax
  130. #define _inc(reg)        _asm inc reg
  131. #define _add(reg, n)        _asm add reg, n
  132. #define _video(func)        _asm mov ah, func _asm int 0x10
  133. #define _video_x        _video
  134. #define _keybrd(func)        _asm mov ah, func _asm int 0x16
  135.  
  136. #else /* not USE_ASSEMBLER */
  137.  
  138. #define _ax    _regs.x.ax
  139. #define _bx    _regs.x.bx
  140. #define _cx    _regs.x.cx
  141. #define _dx    _regs.x.dx
  142. #define _si    _regs.x.si
  143. #define _di    _regs.x.di
  144.  
  145. #define _cy    _regs.x.cflag
  146.  
  147. #define _ah    _regs.h.ah
  148. #define _al    _regs.h.al
  149. #define _bh    _regs.h.bh
  150. #define _bl    _regs.h.bl
  151. #define _ch    _regs.h.ch
  152. #define _cl    _regs.h.cl
  153. #define _dh    _regs.h.dh
  154. #define _dl    _regs.h.dl
  155.  
  156. #define _es    _segregs.es
  157. #define _cs    _segregs.cs
  158. #define _ss    _segregs.ss
  159. #define _ds    _segregs.ds
  160.  
  161. #define    _byte            (unsigned char)
  162. #define _alloc_regs        union REGS _regs
  163. #define _alloc_regs_x        union REGS _regs; struct SREGS _segregs
  164. #define _push(reg)
  165. #define _pop(reg)
  166. #define _mov(dest,source)    dest = source
  167. #define _mov_ax            _mov
  168. #define _inc(reg)        (reg)++
  169. #define _add(reg, n)        (reg) += n;
  170. #define _video(func)        _ah = func; int86 (0x10, &_regs, &_regs)
  171. #define _video_x(func)        _ah = func; \
  172.                 int86x (0x10, &_regs, &_regs, &_segregs)
  173. #define _keybrd(func)        _ah = func; int86 (0x16, &_regs, &_regs)
  174.  
  175. #endif /* not USE_ASSEMBLER */
  176.  
  177. /* Terminal paramters.  */
  178.  
  179. unsigned char term_attrib = 0x07;
  180. unsigned char term_top_row = 0x00;
  181. unsigned char term_left_col = 0x00;
  182. unsigned char term_bot_row = 0x24;
  183. unsigned char term_right_col = 0x79;
  184.  
  185. int terminal_rows = 80;        /* This should read `cols', Brian... */
  186. int terminal_lines = 25;
  187.  
  188. #pragma pack(1)
  189. struct video_state_info
  190. {
  191.   unsigned int    off_static_tab;        /* offset of static info table */
  192.   unsigned int    seg_static_tab;        /* segment of static info table */
  193.   unsigned char    video_mode;        /* videomode */
  194.   unsigned int    num_cols;        /*  */
  195.   unsigned int    regen_length;        /*  */
  196.   unsigned int    regen_offset;        /*  */
  197.   unsigned int    cursor_pos[8];        /*  */
  198.   unsigned int    cursor_mode;        /*  */
  199.   unsigned char    active_page;        /*  */
  200.   unsigned int    crtc_address;        /*  */
  201.   unsigned char    reg_3x8;        /*  */
  202.   unsigned char    reg_3x9;        /*  */
  203.   unsigned char    num_rows;        /*  */
  204.   unsigned int    char_height;        /*  */
  205.   unsigned char    act_disp_cc;        /*  */
  206.   unsigned char    alt_disp_cc;        /*  */
  207.   unsigned int num_colors;        /*  */
  208.   unsigned char    num_pages;        /*  */
  209.   unsigned char    scan_lines;        /*  */
  210.   unsigned char    prim_char_blk;        /*  */
  211.   unsigned char    sec_char_blk;        /*  */
  212.   unsigned char    misc_info;        /*  */
  213.   unsigned char    reserved_2e_30[3];    /* reserved bytes */
  214.   unsigned char    avl_memory;        /*  */
  215.   unsigned char    save_ptr_state;        /*  */
  216.   unsigned char    reserved_33_3f[13];    /* reserved bytes */
  217. };
  218. #pragma pack()
  219.  
  220.  
  221. /* Initialize screen output.  Currently this just sets the screen
  222.    dimensions.  */
  223. void
  224. opsys_init_terminal (void)
  225. {
  226. #ifndef USE_ANSI
  227.  
  228.   unsigned int segm;
  229.   unsigned int offs;
  230.   char check;
  231.   struct video_state_info _far *video_state
  232.     = (struct video_state_info _far *)
  233.       alloca (sizeof (struct video_state_info));
  234.   _alloc_regs_x;
  235.  
  236.   if (!video_state)
  237.     {
  238.       fprintf (stderr, "Stack overflow.\n");
  239.       abort ();
  240.     }
  241.  
  242.   segm = FP_SEG (video_state);
  243.   offs = FP_OFF (video_state);
  244.  
  245.   _mov (_bx, 0x00);        /* "implementation type" (???) */
  246.   _mov_ax (_es, segm);
  247.   _mov (_di, offs);
  248.  
  249.   _video_x (0x1b);        /* Return state information function */
  250.   _mov (check, _al);
  251.  
  252.   if (check == 0x1b)
  253.     {
  254.       terminal_lines = video_state->num_rows;
  255.       terminal_rows = (int) video_state->num_cols;
  256.     }
  257.   else
  258.     {
  259. #if 0                /* shut up! (on public demand) */
  260.       fprintf (stderr, "\aNot a VGA terminal, assuming 80x25 BW.\n");
  261. #endif
  262.       term_normal_attrib = FG_BG (WHITE, BLACK);
  263.       term_inverse_attrib = FG_BG (BLACK, WHITE);
  264.     }
  265.  
  266.   term_attrib = term_normal_attrib;
  267.  
  268.   term_top_row = 0x00;
  269.   term_left_col = 0x00;
  270.   term_bot_row = (unsigned char) (terminal_lines - 1);
  271.   term_right_col = (unsigned char) (terminal_rows - 1);
  272.  
  273. #endif /* not USE_ANSI */
  274.  
  275.   clrscr ();
  276. }
  277.  
  278.  
  279. /* Write the character C, using TERM_ATTRIB as attribute, and step one
  280.    column right.  */
  281.  
  282. void
  283. write_char (int c)
  284. {
  285. #ifndef USE_ANSI
  286.   _alloc_regs;
  287.  
  288.   _video (0x0f);        /* Get active page into _bh.  */
  289.  
  290.   _mov    (_al, _byte c);        /* The character to write.  */
  291.   _mov    (_cx, 0x01);        /* Write it once.  */
  292.   _mov    (_bl, term_attrib);    /* With current attribute.  */
  293.   _video (0x09);
  294.  
  295.   _video (0x03);        /* Read character position function. */
  296.   _inc    (_dl);            /* increment column */
  297.   _video (0x02);        /* Set character position function. */
  298.  
  299. #else /* USE_ANSI */
  300.  
  301.   putchar (c);
  302.  
  303. #endif /* USE_ANSI */
  304. }
  305.  
  306.  
  307. /* Move the cursor to X, Y */
  308.  
  309. void
  310. opsys_goto_pos (int x, int y)
  311. {
  312. #ifndef USE_ANSI
  313.   set_cursor_position ((unsigned char) y, (unsigned char) x);
  314. #else
  315.   printf ("\033[%d;%dH", y, x);
  316. #endif
  317. }
  318.  
  319.  
  320. /* Clear the screen. */
  321.  
  322. void
  323. clrscr (void)
  324. {
  325. #ifndef USE_ANSI
  326.   scroll_up_active_page (0, term_attrib, term_top_row, term_left_col,
  327.                      term_bot_row, term_right_col);
  328. #else /* USE_ANSI */
  329.   fputs ("\033[2j", stdout);
  330. #endif /* USE_ANSI */
  331. }
  332.  
  333.  
  334. /* Clear from the cursor to the end of screen. */
  335.  
  336. void
  337. clreop (void)
  338. {
  339. #ifndef USE_ANSI
  340.  
  341.   unsigned char row;
  342.   _alloc_regs;
  343.  
  344.   _video (0x0f);        /* Get active page into _bh */
  345.   _video (0x03);        /* Read character position function. */
  346.   _inc (_dh);
  347.   _mov (row, _dh);        /* row from which to blank */
  348.  
  349.   clreol ();
  350.   scroll_up_active_page (0, term_attrib, row, term_left_col,
  351.                      term_bot_row, term_right_col);
  352.  
  353. #else /* USE_ANSI */
  354.  
  355.   clear_eop_slowly ();
  356.  
  357. #endif /* USE_ANSI */
  358. }
  359.  
  360.  
  361. /* Clear from the cursor to the end of the cursor's line. */
  362.  
  363. void
  364. clreol (void)
  365. {
  366. #ifndef USE_ANSI
  367.  
  368.   int col = 0;
  369.   _alloc_regs;
  370.  
  371.   _video (0x0f);        /* Get active page into _bh */
  372.   _video (0x03);        /* Read character position function. */
  373.  
  374.   _mov (col, _dl);
  375.  
  376.   col = term_right_col - col + 1;
  377.   _mov (_cx, col);
  378.  
  379.   _mov (_al, ' ');
  380.   _mov (_bl, term_attrib);
  381.   _video (0x09);        /* Write characters at cursor position. */
  382.  
  383. #else /* USE_ANSI */
  384.  
  385.   fputs ("\033[K", stdout);
  386.  
  387. #endif /* USE_ANSI */
  388. }
  389.  
  390.  
  391. void
  392. set_cursor_position (unsigned char row, unsigned char col)
  393. {
  394.   _alloc_regs;
  395.  
  396.   _video (0x0f);        /* Get active page into _bh */
  397.   _mov (_dh, row);
  398.   _mov (_dl, col);
  399.   _video (0x02);        /* set cursor position function */
  400. }
  401.  
  402.  
  403. void
  404. scroll_up_active_page (unsigned char lines, unsigned char attrib,
  405.                unsigned char top_row, unsigned char left_col,
  406.                unsigned char bot_row, unsigned char right_col)
  407. {
  408.   _alloc_regs;
  409.  
  410.   _mov (_al, lines);
  411.   _mov (_bh, attrib);
  412.   _mov (_cl, left_col);
  413.   _mov (_ch, top_row);
  414.   _mov (_dl, right_col);
  415.   _mov (_dh, bot_row);
  416.  
  417.   _video (0x06);
  418. }
  419.  
  420.  
  421. void
  422. textattr (unsigned char attrib)
  423. {
  424. #ifndef USE_ANSI
  425.  
  426.   term_attrib = attrib;
  427.  
  428. #else /* USE_ANSI */
  429.  
  430.   if (attrib == INVERSE_ATTRIB)
  431.     fputs ("\033[7m", stdout);
  432.   else
  433.     fputs ("\033[0m", stdout);
  434.  
  435. #endif /* USE_ANSI */
  436. }
  437.  
  438.  
  439. /* Get a character.  */
  440.  
  441. int
  442. pc_getc (void)
  443. {
  444.   int c = getch ();
  445.  
  446.   if (c != 0x00 && c != 0xE0)
  447.     return c;
  448.   else
  449.     switch (getch ())
  450.       {
  451.       case 71:
  452.     /* Home.  */
  453.     return 'b';
  454.  
  455.       case 73:
  456.     /* Page up.  */
  457.       case 83:
  458.     /* Del.  */
  459.     return 0177;
  460.  
  461.       case 81:
  462.     /* Page down.  */
  463.       default:
  464.     return ' ';
  465.       }
  466. }
  467.  
  468.  
  469. /* 
  470.  * Local Variables:
  471.  * mode:C
  472.  * ChangeLog:ChangeLog
  473.  * compile-command:make
  474.  * End:
  475.  */
  476.